package com.crm.system.controller.returnMoney;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DataResponse;
import com.crm.common.model.DhPageInfo;
import com.crm.common.model.DhResponse;
import com.crm.common.model.Enum.ResponseCodeEnum;
import com.crm.common.util.DateUtil;
import com.crm.common.util.ESUtil;
import com.crm.common.util.PathUtil;
import com.crm.model.entity.returnMoney.BankFlow;
import com.crm.model.entity.returnMoney.ReturnMoneyLog;
import com.crm.model.qo.customerManager.CustomerPayQO;
import com.crm.model.qo.returnMoney.BankFlowQO;
import com.crm.model.qo.returnMoney.BankFlowRelateQO;
import com.crm.model.qo.returnMoney.BankFlowRelieveQO;
import com.crm.model.vo.customerContractManager.CustomerContractDetailVO;
import com.crm.model.vo.orderManager.OrderDetailVO;
import com.crm.model.vo.returnMoney.*;
import com.crm.system.service.cluePoolManager.ExcelUtil;
import com.crm.system.service.returnMoney.BankFlowService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

/**
 * @author yuanyunfeng
 * @date 2021/7/26 9:46
 */
@RestController
@RequestMapping("/bankFlow")
@Slf4j
public class BankFlowController {

    @Value("${esurl}")
    public String ESurl;

    @Autowired
    private BankFlowService bankFlowService;


    /**
     * 下载模版
     *
     * @param response
     */
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        InputStream fis = null;
        OutputStream os = null;
        String path = "";
        try {
            String fileName = "bankImport.xlsx";
            //根据系统来判断取相对路径还是绝对路径
            String osName = System.getProperty("os.name");
            if (osName.toLowerCase().startsWith("win")) {
                path = Thread.currentThread().getContextClassLoader().getResource("").getPath() + PathUtil.getDownPath() + fileName;
            } else {
                path = PathUtil.getDownPath() + fileName;
            }
            fileName = new java.net.URLDecoder().decode(fileName, "utf-8");
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "iso8859-1"));
            //以流的形式下载文件
            fis = new BufferedInputStream(new FileInputStream(path));
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(fis);
            os = new BufferedOutputStream(response.getOutputStream());
            xssfWorkbook.write(os);
            os.flush();
        } catch (Exception e) {
            log.error("downloadBankTemplate error:", e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e1) {
                    log.error("downloadBankTemplate error:", e1);
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e2) {
                    log.error("downloadBankTemplate error:", e2);
                }
            }
        }
    }


    /**
     * 导入功能
     *
     * @param request
     * @param file
     * @return
     */
    @PostMapping("/import")
    public DataResponse callImport(HttpServletRequest request,
                                   @RequestParam MultipartFile file) throws IOException {
        try {
            ExcelUtil excelUtil = new ExcelUtil();
            List<BankImportModel> bankList = excelUtil.excelImport(file.getInputStream(), BankImportModel.class);//1.读取前端的excel文件并转换成list集合
            if (bankList == null || bankList.size() == 0) {
                return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
            }
            BankImportVO result = bankFlowService.importBankData(bankList);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), result);
        } catch (Exception e) {
            log.error("bankImport error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), e);
        }
    }


    /**
     * @return com.crm.common.model.DataResponse
     * @author yuanyunfeng
     * @Description 新增单条流水记录
     * @date 2021/11/24 14:37
     * @Param [bankReq]
     **/
    @PostMapping("/insert")
    public DataResponse insertBankFlow(@RequestBody BankImportModel bankReq) {
        String responsecode = bankFlowService.insertBankFlow(bankReq);
        return new DhResponse(responsecode);
    }


    /**
     * 获取文件上传进度
     *
     * @return
     */
    @RequestMapping("/getUploadProgress")
    @ResponseBody
    public BankProcessEntity getUploadProgress() {
        BankProcessEntity bankProcessEntity = bankFlowService.queryUploadProcess();
        return bankProcessEntity;
    }


    /**
     * 取消上传
     *
     * @param readRow 当前读到多少行
     * @return
     */
    @GetMapping("/cancel")
    @ResponseBody
    public DataResponse cancelUploadBank(String readRow) {
        try {
            String message = bankFlowService.cancelUpload(readRow);
            return new DataResponse(ResponseCodeEnum.OK.getResponseCode(), message);
        } catch (Exception e) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), e);
        }

    }


    /**
     * 列表查询银行导入流水
     *
     * @param pageIndex
     * @param pageSize
     * @param sortName
     * @param sortOrder
     * @return
     */
    @GetMapping("/queryData")
    public DataResponse queryBankFlowData(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                          @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                          @RequestParam(value = "sortName", required = false) String sortName,//排序列名字
                                          @RequestParam(value = "sortOrder", required = false) String sortOrder,//排序规则(asc/desc)
                                          BankFlowQO bankFlowQO
    ) {
        try {
            DhPageInfo<BankFlowQueryVO> bankDataList = bankFlowService.queryBankFlowData(pageIndex, pageSize, sortName, sortOrder, bankFlowQO);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), bankDataList);
        } catch (Exception e) {
            log.error("queryBankData error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }

    }


    /**
     * 流水管理-查询当月导入总金额、未分配总金额
     *
     * @return
     */
    @GetMapping("/queryMonthTotal")
    private DataResponse queryMonthMoneyTotal(@RequestParam(value = "queryYear", required = false) String queryYear,//查询年份
                                              @RequestParam(value = "queryMonth", required = false) String queryMonth//查询月份
    ) {
        BankFlowDataVO bankTotal = bankFlowService.queryMonthMonthTotal(queryYear, queryMonth);
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), bankTotal);
    }


    /**
     * 流水关联
     *
     * @param relateQO
     * @return
     * @throws ParseException
     */
    @PostMapping("/relatedOrder")
    public DataResponse relatedOrder(@RequestBody BankFlowRelateQO relateQO) throws ParseException {
        Map<String, String> map = bankFlowService.relatedOrder(relateQO);
        ESUtil.syncOrder(relateQO.getProductOrderId(), ESurl);
        String code = map.get("code");
        String data = map.get("data");
        return new DhResponse(code, data);
    }


    /**
     * @return com.crm.common.model.DataResponse
     * @author yuanyunfeng
     * @Description 调减流水
     * @date 2021/12/1 10:29
     * @Param [flowId, modifyMoney, modifyReson]
     **/
    @PostMapping("/subAvailableAmount")
    public DataResponse subAvailableAmount(@RequestParam(value = "flowId", required = true) String flowId,
                                           @RequestParam(value = "modifyMoney", required = true) BigDecimal modifyMoney,
                                           @RequestParam(value = "modifyReason", required = true) String modifyReason) {
        String responseCode = bankFlowService.subAvailableAmount(flowId, modifyMoney, modifyReason);
        return new DhResponse(responseCode);
    }


    /**
     * @return com.crm.common.model.DataResponse
     * @author yuanyunfeng
     * @Description 根据流水id查询流水基本信息
     * @date 2021/11/9 9:44
     * @Param [flowId]
     **/
    @GetMapping("/queryInfo")
    public DataResponse queryById(@RequestParam("flowId") String flowId) {
        if (StringUtils.isBlank(flowId)) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "请选择需要查询的记录！");
        }
        BankFlowQueryVO bf = bankFlowService.selectByFlowId(flowId);
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), bf);
    }


    /**
     * 当前流水关联明细
     *
     * @param flowId
     * @return
     */
    @GetMapping("/query/relate")
    public DataResponse queryById(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                  @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                  @RequestParam("flowId") String flowId) {
        if (StringUtils.isBlank(flowId)) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "请选择需要查询的记录！");
        }
        DhPageInfo<BankFlowRelateVO> bankFlowRelateList = bankFlowService.queryBankRelatedByFlowId(pageIndex, pageSize, flowId);
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), bankFlowRelateList);
    }


    /**
     * 查询当前流水的操作记录
     *
     * @param pageIndex
     * @param pageSize
     * @param flowId
     * @return
     */
    @GetMapping("/query/operatorLog")
    public DataResponse queryOperatorLog(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                         @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                         @RequestParam(value = "flowId", required = false) String flowId,
                                         @RequestParam(value = "orderNumber", required = false) String orderNumber,
                                         @RequestParam(value = "payNumber", required = false) String payNumber) {
        if (StringUtils.isBlank(flowId)) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "请选择需要查询的记录！");
        }
        DhPageInfo<BankFlowReturnLogVO> moneyLogList = bankFlowService.queryOperatorLog(pageIndex, pageSize, flowId, orderNumber, payNumber);
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), moneyLogList);
    }


    /**
     * 根据订单编号查询 订单详情、产品明细、合同
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/queryByOrderNumber")
    public DataResponse queryByOrderNumber(@RequestParam(value = "pageIndex", required = false) Integer pageIndex,//页码
                                           @RequestParam(value = "pageSize", required = false) Integer pageSize,//分页大小
                                           @RequestParam("orderNumber") String orderNumber) {
        if (StringUtils.isBlank(orderNumber)) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "订单编码不能为空！");
        }
        //判断订单是否存在
        String productOrderId = bankFlowService.queryOrderId(orderNumber);
        if (StringUtils.isNotBlank(productOrderId)) {
            AssociatedOrderVO associatedOrderVO = bankFlowService.queryByOrderNumber(productOrderId, pageIndex, pageSize);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), associatedOrderVO);
        }
        return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "此订单不存在！");
    }


    /**
     * 查询回款记录
     *
     * @param pageIndex
     * @param pageSize
     * @param sortName
     * @param sortOrder
     * @param flowId
     * @param orderNumber
     * @return
     */
    @GetMapping("/query/returnMoney")
    public DataResponse queryReturnMoney(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                         @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                         @RequestParam(value = "sortName", required = false) String sortName,//排序列名字
                                         @RequestParam(value = "sortOrder", required = false) String sortOrder,
                                         @RequestParam("flowId") String flowId,
                                         @RequestParam("orderNumber") String orderNumber,
                                         @RequestParam("payNumber") String payNumber) {
        if (StringUtils.isBlank(orderNumber) && StringUtils.isBlank(payNumber)) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "查询编码不能为空！");
        }
        DhPageInfo<BankOrderReturn> orderReturnLogs = bankFlowService.queryReturnMoney(pageIndex, pageSize, flowId, orderNumber, payNumber);
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), orderReturnLogs);
    }


    /**
     * 解除关联
     *
     * @return
     */
    @PostMapping("/relieve")
    public DataResponse relieveBank(@RequestBody BankFlowRelieveQO relieveQO) {
        String result = bankFlowService.relieveBank(relieveQO);
        if (!"操作完成".equals(result)) {
            return new DhResponse(ResponseCodeEnum.RELATE_BANK_ERROR.getResponseCode(), result);
        }
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), result);
    }


    /**
     * @return com.crm.common.model.DataResponse
     * @author yuanyunfeng
     * @Description 删除流水
     * @date 2021/11/17 17:17
     * @Param [flowId]
     **/
    @GetMapping("/delete")
    public DataResponse deleteBankFlow(@RequestParam("flowId") String flowId) {
        if (StringUtils.isBlank(flowId)) {
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "请选择需要删除的记录！");
        }
        String responseCode = bankFlowService.deleteByFlowId(flowId);
        return new DhResponse(responseCode);
    }


    /**
     * 导出银行流水
     *
     * @Param sortName
     * @Param sortOrder
     * @Param bankFlowQO
     * @Param response
     * @Author xielinqi
     * @Date 11:28 上午 2021/11/30
     */
    @GetMapping("/exportBankFlowData")
    private DataResponse exportBankFlowData(@RequestParam(value = "sortName", required = false) String sortName,//排序列名字
                                            @RequestParam(value = "sortOrder", required = false) String sortOrder,//排序规则(asc/desc)
                                            BankFlowQO bankFlowQO, HttpServletResponse response) {
        try {
            String fileName = "银行流水" + DateUtil.formatDate(new Date(), "yyyy-MM-dd HH_mm_ss");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(), "ISO8859-1") + ".xlsx");
            ServletOutputStream out = response.getOutputStream();
            if (bankFlowService.exportBankFlowData(sortName, sortOrder, bankFlowQO, out)) {
                return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), "导出成功");
            }
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(), "导出失败");
        } catch (Exception e) {
            log.error("returnMoney selectReturnMoneyList error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }


}
